package com.changgou.seckill.timer;

import com.changgou.seckill.dao.SeckillGoodsMapper;
import com.changgou.seckill.pojo.SeckillGoods;
import entity.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @author ：hushengjin
 */

@Component
public class SeckillGoodsPushTask {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    @Scheduled(cron = "0/10 * * * * ?")
    public void loadGoodsPushRedis() {
        //获取时间段集合
        List<Date> dateMenus = DateUtil.getDateMenus();
        //循环时间段
        for (Date dateMenu : dateMenus) {
            // namespace=SeckillGoods_2019081308
            String extName = DateUtil.data2str(dateMenu, DateUtil.PATTERN_YYYYMMDDHH);
            //根据时间段查询秒杀商品
            Example example = new Example(SeckillGoods.class);
            Example.Criteria criteria = example.createCriteria();
            // 1)商品必须审核通过的
            criteria.andEqualTo("status", "1");
            // 2)库存必须大于零
            criteria.andGreaterThan("stockCount", 0);
            // 3)开始时间大于等于活动开始时间
            criteria.andGreaterThanOrEqualTo("startTime", dateMenu);
            // 4)当前时间小于开始时间+2小时
            criteria.andLessThan("endTime", DateUtil.addDateHour(dateMenu, 2));
            // 5)排除之前已经加入到redis中的数据
            Set keys = redisTemplate.boundHashOps("SeckillGoods_" + extName).keys();
            if (keys != null && keys.size() > 0) {
                criteria.andNotIn("id", keys);
            }
            //查询数据
            List<SeckillGoods> seckillGoodsList = seckillGoodsMapper.selectByExample(example);
            //将秒杀商品加入redis缓存中
            for (SeckillGoods seckillGoods : seckillGoodsList) {
                redisTemplate.boundHashOps("SeckillGoods_" + extName).put(seckillGoods.getId(), seckillGoods);
                //商品数据队列存储,防止高并发超卖
                Long[] ids = pushIds(seckillGoods.getStockCount(), seckillGoods.getId());
                redisTemplate.boundListOps("SeckillGoodsCountList_" + seckillGoods.getId()).leftPushAll(ids);
                //自增计数器,用来记录商品剩余数量
                redisTemplate.boundHashOps("SeckillGoodsCount").increment(seckillGoods.getId(), seckillGoods.getStockCount());
            }
        }
    }

    /**
     * 将商品id存入数组中
     *
     * @param len
     * @param id
     * @return
     */
    public Long[] pushIds(int len, Long id) {
        Long[] ids = new Long[len];
        Arrays.fill(ids, id);
        return ids;
    }

}
